package com.nullpointer.xchat.database;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.nullpointer.xchat.object.HistoryMessage;
import com.nullpointer.xchat.object.MessageContent;
import com.nullpointer.xchat.object.MessageContent.MsgType;
import com.nullpointer.xchat.utils.KiraGameLog;

public class MessagesDataManager {

	private static MessagesDataManager messagesDataManager;
	private XChatDatabaseHelper helper;
	private SQLiteDatabase database;

	// TABLE NAME
	private static final String TABLE_MESSAGES = XChatDatabaseHelper.TABLE_MESSAGES_NAME;
	private static final String TABLE_HISTORY = XChatDatabaseHelper.TABLE_HISTORY_NAME;

	// MESSAGE COLUMN
	public static final String COLUMN_MESSAGE_ID = "messageId";
	public static final String COLUMN_MESSAGE_CONTENT = "messageContent";
	public static final String COLUMN_MESSAGE_CREATED_AT = "createdAt";
	public static final String COLUMN_MESSAGE_SENDER_ID = "senderId";

	// HISTORY COLUMN
	public static final String COLUMN_HISTORY_LAST_MESSAGE_CONTENT = "lastMessageContent";
	public static final String COLUMN_HISTORY_CREATED_AT = "createdAt";
	public static final String COLUMN_HISTORY_SENDER_ID = "senderId";
	public static final String COLUMN_HISTORY_UNREAD_NUM = "unreadNum";
	public static final String COLUMN_HISTORY_IS_FRIEND = "isFriend";

	public static MessagesDataManager getInstance(Context context) {
		if (messagesDataManager == null) {
			messagesDataManager = new MessagesDataManager(context);
		}
		return messagesDataManager;
	}

	public MessagesDataManager(Context context) {
		helper = new XChatDatabaseHelper(context);
	}

	private void openRead() {
		database = helper.getReadableDatabase();
	}

	private void openWrite() {
		database = helper.getWritableDatabase();
	}

	private void closeDatabase() {
		database.close();
	}

	// MESSAGES
	public List<MessageContent> getMessages(String senderId, int page, int size) {
		List<MessageContent> results = new ArrayList<MessageContent>();
		try {
			openRead();
			// String selection = String.format("%s = '%s'",
			// COLUMN_MESSAGE_SENDER_ID, senderId);
			// KiraGameLog.d("selection " + selection);
			// String orderBy = COLUMN_MESSAGE_CREATED_AT + " DESC";
			// KiraGameLog.d("orderBy " + orderBy);
			String limit = null;
			if (size > 0) {
				limit = String.valueOf(page) + "," + String.valueOf(size);
			}

			// Cursor cursor = database.query(TABLE_MESSAGES, new
			// String[]{COLUMN_MESSAGE_SENDER_ID, COLUMN_MESSAGE_CONTENT}, null,
			// null, null, null, null, null);
			Cursor cursor = database.query(TABLE_MESSAGES, new String[] {
					COLUMN_MESSAGE_SENDER_ID, COLUMN_MESSAGE_CONTENT },
					COLUMN_MESSAGE_SENDER_ID + "=?", new String[] { senderId },
					null, null, null, null);
			// String sql = String.format("SELECT * FROM %s WHERE %s = %s",
			// TABLE_MESSAGES, COLUMN_MESSAGE_SENDER_ID, senderId);
			// Cursor cursor = database.rawQuery(sql, null);
			if (cursor.moveToFirst()) {
				do {
					MessageContent item = convertDataToObject(cursor);
					if (item != null) {
						results.add(item);
					}
				} while (cursor.moveToNext());
			}
			cursor.close();
			closeDatabase();

		} catch (Exception e) {
			e.printStackTrace();
		}
		// Collections.sort(results, new Comparator<MessageContent>() {
		//
		// @Override
		// public int compare(MessageContent before, MessageContent after) {
		// return before.getCreatedAt().compareTo(after.getCreatedAt());
		// }
		// });
		// KiraGameLog.d("size of results: " + results.size());
		return results;
	}

	public MessageContent getLastMessage(String senderId) {
		MessageContent mes = new MessageContent();
		List<MessageContent> list = getMessages(senderId, 0, 2);
		if (list.size() == 0) {
			return null;
		}
		mes = list.get(list.size() - 1);
		return mes;
	}

	// public List<MessageContent> getListHistory() {
	// List<MessageContent> history = new ArrayList<MessageContent>();
	// List<Integer> listLastMessageID = new ArrayList<Integer>();
	// openRead();
	// String sql = String.format(
	// "SELECT %s, MAX(%s) AS ID FROM %s GROUP BY %s ORDER BY %s",
	// COLUMN_MESSAGE_SENDER_ID, COLUMN_MESSAGE_ID, TABLE_MESSAGES,
	// COLUMN_MESSAGE_SENDER_ID, COLUMN_MESSAGE_ID);
	//
	// Cursor cursor = database.rawQuery(sql, null);
	//
	// if (cursor.moveToFirst()) {
	// do {
	// int id = cursor.getInt(cursor.getColumnIndex("ID"));
	// listLastMessageID.add(id);
	// } while (cursor.moveToNext());
	// }
	// closeDatabase();
	//
	// for (Integer id : listLastMessageID) {
	// Message msg = getMessageByID(id);
	// for (int i = 0; i < history.size(); i++) {
	// Message item = history.get(i);
	// if (item.getSenderId().equals(msg.getReceiverId())
	// && item.getReceiverId().equals(msg.getSenderId())) {
	// history.remove(i);
	// break;
	// }
	// }
	//
	// history.add(msg);
	// }
	//
	// Collections.sort(history, new Comparator<Message>() {
	//
	// @Override
	// public int compare(Message lhs, Message rhs) {
	// return lhs.getMessageId() > rhs.getMessageId() ? -1 : 1;
	// }
	// });
	//
	// return history;
	// }


	public void insertMessage(String senderID, MessageContent item) {
		try {
			openWrite();
			ContentValues values = getMessageData(senderID, item);
			database.insert(TABLE_MESSAGES, null, values);
			KiraGameLog.d("add new message to database");
			closeDatabase();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 */
	public void deleteAllMessage() {
		try {
			openWrite();
			database.delete(TABLE_MESSAGES, null, null);
			closeDatabase();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// public void updateMessage(MessageContent msg) {
	// try {
	// openWrite();
	// ContentValues result = new ContentValues();
	// result.put(COLUMN_MESSAGE_STATUS, msg.getMessageStatus());
	//
	// String whereClause = String.format("%s = %s", COLUMN_MESSAGE_ID,
	// msg.getMessageId());
	// database.update(TABLE_MESSAGES, result, whereClause, null);
	// database.close();
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }

	private ContentValues getMessageData(String senderId, MessageContent item) {
		ContentValues result = new ContentValues();
		result.put(COLUMN_MESSAGE_CREATED_AT,
				String.valueOf(new Date().getTime()));
		result.put(COLUMN_MESSAGE_CONTENT, item.toJson());
		// KiraGameLog.d("save id " + Integer.toString(item.getFromUserID()));
		result.put(COLUMN_MESSAGE_SENDER_ID, senderId);
		return result;
	}

	private MessageContent convertDataToObject(Cursor cursor) {
		try {
			return MessageContent.fromJsonToMessageContent(cursor
					.getString(cursor.getColumnIndex(COLUMN_MESSAGE_CONTENT)));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// HISTORY
	public List<HistoryMessage> getHistoryMessages(String senderId, int page,
			int size) {
		List<HistoryMessage> results = new ArrayList<HistoryMessage>();
		try {
			openRead();
			// String selection = String.format("%s = '%s'",
			// COLUMN_HISTORY_SENDER_ID, senderId);
			// KiraGameLog.d("selection " + selection);
			// String orderBy = COLUMN_MESSAGE_CREATED_AT + " DESC";
			// KiraGameLog.d("orderBy " + orderBy);
			String limit = null;
			if (size > 0) {
				limit = String.valueOf(page) + "," + String.valueOf(size);
			}

			// Cursor cursor = database.query(TABLE_MESSAGES, new
			// String[]{COLUMN_MESSAGE_SENDER_ID, COLUMN_MESSAGE_CONTENT}, null,
			// null, null, null, null, null);
			Cursor cursor = database.query(TABLE_HISTORY, new String[] {
					COLUMN_HISTORY_SENDER_ID,
					COLUMN_HISTORY_LAST_MESSAGE_CONTENT,
					COLUMN_HISTORY_UNREAD_NUM, COLUMN_HISTORY_IS_FRIEND },
					COLUMN_HISTORY_SENDER_ID + "=?", new String[] { senderId },
					null, null, null, null);
			// String sql = String.format("SELECT * FROM %s WHERE %s = %s",
			// TABLE_MESSAGES, COLUMN_MESSAGE_SENDER_ID, senderId);
			// Cursor cursor = database.rawQuery(sql, null);
			if (cursor.moveToFirst()) {
				do {
					HistoryMessage item = convertDataToHistoryMessage(cursor);
					if (item != null) {
						results.add(item);
					}
				} while (cursor.moveToNext());
			}
			cursor.close();
			closeDatabase();

		} catch (Exception e) {
			e.printStackTrace();
		}
		// Collections.sort(results, new Comparator<MessageContent>() {
		//
		// @Override
		// public int compare(MessageContent before, MessageContent after) {
		// return before.getCreatedAt().compareTo(after.getCreatedAt());
		// }
		// });
		// KiraGameLog.d("size of results: " + results.size());
		return results;
	}

	public List<HistoryMessage> getAllHistoryMessages(int page, int size) {
		List<HistoryMessage> results = new ArrayList<HistoryMessage>();
		try {
			openRead();
			// String selection = String.format("%s = '%s'",
			// COLUMN_HISTORY_SENDER_ID, senderId);
			// KiraGameLog.d("selection " + selection);
			// String orderBy = COLUMN_MESSAGE_CREATED_AT + " DESC";
			// KiraGameLog.d("orderBy " + orderBy);
			String limit = null;
			if (size > 0) {
				limit = String.valueOf(page) + "," + String.valueOf(size);
			}

			// Cursor cursor = database.query(TABLE_MESSAGES, new
			// String[]{COLUMN_MESSAGE_SENDER_ID, COLUMN_MESSAGE_CONTENT}, null,
			// null, null, null, null, null);
			Cursor cursor = database.query(TABLE_HISTORY, new String[] {
					COLUMN_HISTORY_SENDER_ID,
					COLUMN_HISTORY_LAST_MESSAGE_CONTENT,
					COLUMN_HISTORY_UNREAD_NUM, COLUMN_HISTORY_IS_FRIEND },
					null, null, null, null, null, null);
			// String sql = String.format("SELECT * FROM %s WHERE %s = %s",
			// TABLE_MESSAGES, COLUMN_MESSAGE_SENDER_ID, senderId);
			// Cursor cursor = database.rawQuery(sql, null);
			if (cursor.moveToFirst()) {
				do {
					HistoryMessage item = convertDataToHistoryMessage(cursor);
					if (item != null) {
						results.add(item);
					}
				} while (cursor.moveToNext());
			}
			cursor.close();
			closeDatabase();

		} catch (Exception e) {
			e.printStackTrace();
		}
		// Collections.sort(results, new Comparator<MessageContent>() {
		//
		// @Override
		// public int compare(MessageContent before, MessageContent after) {
		// return before.getCreatedAt().compareTo(after.getCreatedAt());
		// }
		// });
		// KiraGameLog.d("size of results: " + results.size());
		return results;
	}

	private HistoryMessage convertDataToHistoryMessage(Cursor cursor) {
		HistoryMessage historyMessage = new HistoryMessage();
		try {
			historyMessage
					.setMessageContent(MessageContent.fromJsonToMessageContent(cursor.getString(cursor
							.getColumnIndex(COLUMN_HISTORY_LAST_MESSAGE_CONTENT))));
			historyMessage.setUnreadNum(cursor.getInt(cursor
					.getColumnIndex(COLUMN_HISTORY_UNREAD_NUM)));
			int isFriend = cursor.getInt(cursor
					.getColumnIndex(COLUMN_HISTORY_IS_FRIEND));
			historyMessage.setFriend((isFriend == 1) ? true : false);
			return historyMessage;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public void insertHistoryMessage(Integer senderID, MessageContent item,
			int num, boolean isFriend) {
		try {
			openWrite();
			ContentValues values = getHistoryMessageData(senderID, item, num,
					isFriend);
			database.insert(TABLE_HISTORY, null, values);
			KiraGameLog.d("add new history message to database");
			closeDatabase();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private ContentValues getHistoryMessageData(Integer senderId,
			MessageContent item, int num, boolean isFriend) {
		ContentValues result = new ContentValues();
		result.put(COLUMN_HISTORY_CREATED_AT,
				String.valueOf(new Date().getTime()));
		result.put(COLUMN_HISTORY_LAST_MESSAGE_CONTENT, item.toJson());
		// KiraGameLog.d("save id " + Integer.toString(item.getFromUserID()));
		result.put(COLUMN_HISTORY_SENDER_ID, senderId);
		result.put(COLUMN_HISTORY_UNREAD_NUM, num);
		result.put(COLUMN_HISTORY_IS_FRIEND, isFriend ? 1 : 0);
		return result;
	}

	public void updateHistoryMessage(Integer senderID, MessageContent item,
			int num) {
		openWrite();
		ContentValues result = new ContentValues();
		result.put(COLUMN_HISTORY_LAST_MESSAGE_CONTENT, item.toJson());
		result.put(COLUMN_HISTORY_UNREAD_NUM, num);
		result.put(COLUMN_MESSAGE_CREATED_AT,
				String.valueOf(new Date().getTime()));
		database.update(TABLE_HISTORY, result,  COLUMN_HISTORY_SENDER_ID
				+ " = ?", new String[] { String.valueOf(senderID) });
		database.close();
	}

	public void resetHistoryMessageUnreadNum(Integer senderID) {
		openWrite();
		ContentValues result = new ContentValues();
		result.put(COLUMN_HISTORY_UNREAD_NUM, 0);
		database.update(TABLE_HISTORY, result, COLUMN_HISTORY_SENDER_ID
				+ " = ?", new String[] { String.valueOf(senderID) });
		database.close();
	}

	public void markFriend(Integer senderID, boolean isMark) {
		openWrite();
		ContentValues result = new ContentValues();
		result.put(COLUMN_HISTORY_IS_FRIEND, isMark ? 1 : 0);
		database.update(TABLE_HISTORY, result, COLUMN_HISTORY_SENDER_ID
				+ " = ?", new String[] { String.valueOf(senderID) });
		database.close();
	}

	public boolean checkIsFriend(Integer senderID, String name) {
		int isFriend = 0;
		try {
			openRead();
			Cursor cursor = database.query(TABLE_HISTORY, new String[] {
					COLUMN_HISTORY_SENDER_ID, COLUMN_HISTORY_IS_FRIEND },
					COLUMN_HISTORY_SENDER_ID + "=?",
					new String[] { Integer.toString(senderID) }, null, null,
					null, null);
			if (cursor.getCount() > 0) {
				if (cursor.moveToFirst()) {
					isFriend = cursor.getInt(cursor
							.getColumnIndex(COLUMN_HISTORY_IS_FRIEND));
				}
			} else {
				MessageContent messageContent = new MessageContent();
				messageContent.setAvartar(null);
				messageContent.setContent("");
				messageContent.setFromUserID(senderID);
				messageContent.setMsgType(MsgType.TEXT);
				messageContent.setName(name);
				insertHistoryMessage(senderID, messageContent, 0, false);
			}
			cursor.close();
			closeDatabase();

		} catch (Exception e) {
			e.printStackTrace();
			isFriend = 0;
		}
		return (isFriend == 1) ? true : false;
	}

	public void deleteHistoryMessageUnMarkFriend() {
		try {
			openWrite();
			database.delete(TABLE_HISTORY, COLUMN_HISTORY_IS_FRIEND + " = ?",
					new String[] { "0" });
			closeDatabase();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
